package com.example.wexcle.demos.web.service.impl;

import com.alibaba.excel.EasyExcel;
import com.example.wexcle.demos.web.entity.File;
import com.example.wexcle.demos.web.service.ExcelExportService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;


import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 提供了一个方法exportDataToExcel用于将数据导出到Excel文件中。这个方法使用了异步执行和EasyExcel库来简化Excel文件的创建过程
 */
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
@Service
public class ExcelExportServiceImpl implements ExcelExportService {
    private final ThreadPoolTaskExecutor taskExecutor;

    /**
     *
     * @param dataList 数据库中查出的数据100万，分成10份每份10万条数据
     * @param outputDir 地址
     * @return
     */
    @Override
    //调用者可以使用这个CompletableFuture对象来查询异步任务的状态、等待任务完成或获取任务的结果。
    public CompletableFuture<String> exportDataToExcel(List<File> dataList, String outputDir) {
        try {
            //在指定的outputDir（D:\\data）目录下创建一个临时文件，文件名以"excelFilePre"为前缀，以".xlsx"为后缀。这个临时文件将用于存放导出的Excel数据。
            Path temproaryFilePath = Files.createTempFile(Paths.get(outputDir), "excelFilePre", ".xlsx");
//使用CompletableFuture.supplyAsync方法来异步执行Excel的导出逻辑
            return CompletableFuture.supplyAsync(() -> {
                //创建一个FileOutputStream来写入临时文件
                try (OutputStream outputStream = new FileOutputStream(temproaryFilePath.toFile())) {
                    //EasyExcel.write方法指定输出流和要写入的数据类型，此处File是实体类（自定义冲突了）
                    EasyExcel.write(outputStream, File.class).sheet("文件信息").doWrite(dataList);
                    return temproaryFilePath.toString();//返回临时文件路径
                } catch (IOException e) {
                    throw new RuntimeException("Failed to export Excel file", e);
                }
            }, taskExecutor);
            //参数taskExecutor是一个ThreadPoolTaskExecutor，它指定了异步任务应该在哪个线程池中执行
            //supplyAsync方法的第二个参数是一个Executor，用于执行异步任务。在这个例子中，使用了taskExecutor作为执行器
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



}



